package org.topteam.ui.easyui;

import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import java.io.IOException;
import java.util.*;

/**
 * 一次JSP页面EasyUI控件解析的上下文。
 * 从解析Body开始到Body结束，所有控件的一些属性会被暂存
 * 在解析body结束的时候，写出所有控件前端渲染的方法。
 * Created by 枫 on 2014/8/7.
 */
public class RenderContext {

    private final Map<String, TagRender> tags = new HashMap<String, TagRender>();
    private final List<EventListenerTag> events = new ArrayList<EventListenerTag>();

    public void putTag(TagRender tag) throws JspTagException {
        if (tag != null && tag.getId() != null) {
            if (tags.containsKey(tag.getId())) {
                throw new JspTagException("存在重复的ID：" + tag.getId());
            }
            tags.put(tag.getId(), tag);
        }
    }

    public TagRender getTag(String id) {
        return tags.get(id);
    }

    public void putEvent(EventListenerTag eventTag) {
        events.add(eventTag);
    }

    public void write(JspWriter out) throws IOException {
        ScriptWriter sw = new ScriptWriter();
        for (Iterator<String> iterator = tags.keySet().iterator(); iterator.hasNext(); ) {
            String tagId = iterator.next();
            TagRender tag = tags.get(tagId);
            Map<String, String> eventMap = getEvents(tagId);
            String tagScript = getTagScript(tag, eventMap);
            sw.write(tagScript);
            sw.write("\n");
        }
        out.write(sw.toString());
    }

    private String getTagScript(TagRender tag, Map<String, String> eventMap) {
        StringBuilder sb = new StringBuilder();
        sb.append("$('#").append(tag.getId()).append("').").append(tag.getEasyuiTag()).append("(");
        if(!tag.isJqueryEventBind()){
            if(eventMap.size()>0){
                sb.append("{\n");
            }
            for (Iterator<String> iterator = eventMap.keySet().iterator(); iterator.hasNext(); ) {
                String event = iterator.next();
                String listener = eventMap.get(event);
                sb.append(event).append(":").append("function(){").append(listener).append(".apply(arguments);}");
                if (iterator.hasNext()) {
                    sb.append(",");
                }
            }
            if(eventMap.size()>0){
                sb.append("\n}");
            }
        }
        sb.append(");");

        if(tag.isJqueryEventBind()){
            for (Iterator<String> iterator = eventMap.keySet().iterator(); iterator.hasNext(); ) {
                String event = iterator.next();
                String listener = eventMap.get(event);
                sb.append("$('#").append(tag.getId()).append("').bind(");
                sb.append("'").append(event).append("',").append("function(){").append(listener).append(".apply(arguments);}");
                sb.append(");");
            }
        }
        return sb.toString();
    }

    private Map<String, String> getEvents(String tagId) {
        Map<String, String> eventMap = new HashMap<String, String>();
        for (EventListenerTag event : events) {
            if (event.getFor().equals(tagId)) {
                eventMap.put(event.getEvent(), event.getListener());
            }
        }
        return eventMap;
    }
}
